package com.yiquan.search.service;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.yiquan.search.client.CommentClient;
import com.yiquan.search.client.UserClient;
import com.yiquan.search.client.VideoClient;
import com.yiquan.search.dao.es.EsUserDao;
import com.yiquan.search.dao.es.EsVideoDao;
import com.yiquan.search.entity.Comment;
import com.yiquan.search.entity.User;
import com.yiquan.search.entity.Video;
import com.yiquan.search.entity.vo.SearchUserPageVO;
import com.yiquan.search.entity.vo.SearchVideoPageVO;
import entity.PageResult;
import entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.elasticsearch.index.query.CommonTermsQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import sun.rmi.server.InactiveGroupException;
import util.ObjectUtils;

import java.util.*;

import static com.yiquan.search.interceptor.HotSearchInterceptor.HOT_WORD;

/**
 * @author xieyl
 * @create 2022/1/25 21:26
 */
@Service
@Slf4j
public class SearchService {
    @Autowired
    private EsUserDao esUserDao;

    @Autowired
    private EsVideoDao esVideoDao;

    private ElasticsearchTemplate esTemplate;

    @Autowired
    private UserClient userClient;

    @Autowired
    private CommentClient commentClient;

    @Autowired
    private VideoClient videoClient;

    @Autowired
    private RedisTemplate redisTemplate;

    public void save() {

    }

    public List<SearchUserPageVO> searchUser(String keyWord, Long userId) {
        CommonTermsQueryBuilder queryBuilder = QueryBuilders.commonTermsQuery("username", keyWord);
        Iterable<User> search = esUserDao.search(queryBuilder);
        List<User> userList = Lists.newArrayList(search);
        List<SearchUserPageVO> searchUserPageVOList = new ArrayList<>();
        userList.forEach(user -> {
            searchUserPageVOList.add(searchUserPageVOCreater(user, userId));
        });
        return searchUserPageVOList;
    }

    public List<SearchVideoPageVO> searchVideo(String keyWord) {

        CommonTermsQueryBuilder queryBuilder = QueryBuilders.commonTermsQuery("video", keyWord);
        ArrayList<Video> videos = Lists.newArrayList(esVideoDao.search(queryBuilder));
        /**
         * 检索视频描述检索不出换一种检索
         */
        if (videos == null && videos.size() <= 0) {

        }
        List<SearchVideoPageVO> searchVideoPageVOList = new ArrayList<>();
        videos.forEach(video -> {
            Map map = new HashMap<>();
            map.put("parent_id", video.getVideo_id());
            map.put("parent_type", 0);
            Comment comment = (Comment) commentClient.getCommentByVideoId(map).getData();
            User user = (User) userClient.findByUserId(video.getVideo_uid()).getData();
            searchVideoPageVOList.add(searchVideoPageVOCreater(comment, user, video));
        });

        return searchVideoPageVOList;
    }

    public SearchVideoPageVO searchVideoPageVOCreater(Comment comment, User user, Video video) {
        SearchVideoPageVO searchVideoPageVO = new SearchVideoPageVO();

        /**
         * 视频相关信息
         */
        BeanUtils.copyProperties(video, searchVideoPageVO);

        /**
         * 拥有者相关信息
         */
        searchVideoPageVO.setUserId(searchVideoPageVO.getVideo_uid());
        searchVideoPageVO.setOwnerAvatar(user.getAvatar());
        searchVideoPageVO.setOwnerNickname(user.getNick_name());

        /**
         * 评论相关信息
         */
        searchVideoPageVO.setComment(comment.getContent());
        searchVideoPageVO.setCommentThumb(comment.getThump());
        searchVideoPageVO.setCommentUserId(comment.getUser_id());
        searchVideoPageVO.setCommentUserAvatar(comment.getAvatar());
        searchVideoPageVO.setCommentUserNickname(comment.getNick_name());

        return searchVideoPageVO;

    }


    public SearchUserPageVO searchUserPageVOCreater(User user, Long userId) {
        SearchUserPageVO searchUserPageVO = new SearchUserPageVO();
        BeanUtils.copyProperties(user, searchUserPageVO);
        Boolean isFollow = (Boolean) userClient.isFollow(userId, user.getUser_id()).getData();
        searchUserPageVO.setIsFollow(isFollow);
        Map map = new HashMap<>();
        map.put("userId", user.getUser_id());
        LinkedHashMap data = (LinkedHashMap) videoClient.searchVideo(map).getData();
        Object rows = data.get("rows");
        List<Video> videos = JSON.parseArray(JSON.toJSONString(rows), Video.class);
        searchUserPageVO.setVideoList(videos);
        return searchUserPageVO;
    }

    public List<Map> getHotSearchWord() {
        Set<ZSetOperations.TypedTuple<Object>> typedTupleSet = redisTemplate.opsForZSet().reverseRangeByScoreWithScores(HOT_WORD, 1, 10);
        List hotSearchWordList = new ArrayList();
        Iterator<ZSetOperations.TypedTuple<Object>> iterator = typedTupleSet.iterator();
        while (iterator.hasNext()) {
            ZSetOperations.TypedTuple<Object> typedTuple = iterator.next();
            Object value = typedTuple.getValue();
            Double score1 = typedTuple.getScore();
            Map map = new HashMap();
            map.put("keyWord", (String) value);
            map.put("nums", score1.intValue());
            hotSearchWordList.add(map);
        }
        return hotSearchWordList;
    }

    public void setHotSearchWord(String hotWord) {
        redisTemplate.opsForZSet().incrementScore(HOT_WORD, hotWord, 1L);
    }


    public PageResult<SearchUserPageVO> searchUserNoEs(String keyword, Integer page, Long userId) {
        Map map = new HashMap();
        map.put("nickname", keyword);
        Result search = userClient.findSearch(map, page, 10);
        LinkedHashMap data = (LinkedHashMap) search.getData();
        Object rows = data.get("rows");
        List<User> users = JSON.parseArray(JSON.toJSONString(rows), User.class);
        List<SearchUserPageVO> searchUserPage = new ArrayList<>();
        users.forEach((user -> {
            SearchUserPageVO searchUserPageVO = this.searchUserPageVOCreater(user, userId);
            searchUserPage.add(searchUserPageVO);
        }));
        return  new PageResult<SearchUserPageVO>(Long.valueOf((Integer)data.get("total")),searchUserPage);
    }
}
